﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Kailua.net.windward.utils;

namespace ArrowScheduleCore
{
    /// <summary>
    /// When to run this scheduled event. RunTime and runZone are in local time for the user while RunLast and
    /// RunNext are in UTC time.
    /// </summary>
    public abstract class SchedulePeriod
    {

        /// <summary>
        /// The schedule type. This will always be 0...3.
        /// </summary>
        public enum REPEAT
        {
            /// <summary>
            /// Run daily.
            /// </summary>
            DAILY = 0,
            /// <summary>
            /// Run weekly.
            /// </summary>
            WEEKLY = 1,
            /// <summary>
            /// Run monthly.
            /// </summary>
            MONTHLY = 2,
            /// <summary>
            /// Run yearly.
            /// </summary>
            YEARLY = 3
        };

        /// <summary>
        /// This is local time to run the event. Use with runZone to determine the actual time.
        /// </summary>
        protected DateTime runTime;

        /// <summary>
        /// The timezone in which the time for this event is set.
        /// </summary>
        protected TimeZoneInfo runZone;

        /// <summary>
        /// The culture that the time is set in. This is used to determine what days are the weekend.
        /// </summary>
        protected CultureInfo cultureInfo;

        /// <summary>
        /// Create the object set to now in the local timezone and to the local culture.
        /// </summary>
        protected SchedulePeriod()
        {
            runTime = DateTime.Now;
            runZone = TimeZoneInfo.Local;
            cultureInfo = CultureInfo.CurrentCulture;
        }

        /// <summary>
        /// What day and time to run this on. Time is generally set to 15 minute increments and jobs are run at approximately
        /// the requested time. This in local time (see RunZone for timezone).
        /// </summary>
        public DateTime RunTime
        {
            get { return runTime; }
            set
            {
                Trap.trap(runTime.Kind != DateTimeKind.Local);
                runTime = value;
            }
        }

        /// <summary>
        /// The TimeZone for RunTime.
        /// </summary>
        //public WindwardTimeZone RunZone
        public TimeZoneInfo RunZone
        {
            get { return runZone; }
            set { runZone = value; }
        }

        /// <summary>
        /// The culture of the scheduled item. This determines the calendar used, weekdays, etc.
        /// </summary>
        public CultureInfo Culture
        {
            get { return cultureInfo; }
            set { cultureInfo = (value.CultureTypes & CultureTypes.NeutralCultures) != 0 ? CultureInfo.CurrentCulture : value; }
        }

        /// <summary>
        /// Use this instead of class type only when necessary such as a switch statement.
        /// </summary>
        public abstract REPEAT RepeatType
        {
            get;
        }

        /// <summary>
        /// A human readable description of the period.
        /// </summary>
        public abstract string Description
        {
            get;
        }
    }
}
